/*
 *
 *  Copyright 2015 the original author or authors.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *
 */

package com.gitee.ice1938.swagger2staticdocs.petstore.controller;

import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import static org.springframework.http.MediaType.APPLICATION_XML_VALUE;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;
import static org.springframework.web.bind.annotation.RequestMethod.PUT;

import java.util.List;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.gitee.ice1938.swagger2staticdocs.petstore.model.Pet;
import com.gitee.ice1938.swagger2staticdocs.petstore.model.Pets;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import springfox.petstore.controller.NotFoundException;
import springfox.petstore.repository.MapBackedRepository;

@RestController
@RequestMapping(value = "/pets", produces = { APPLICATION_JSON_VALUE, APPLICATION_XML_VALUE, "application/x-smile" })
// 默认排序Controller是使用tags ，这里使用【A.宠物】进行排序定义
@Tag(description = "宠物的的相关操作", name = "A.宠物")
public class PetController {

	PetRepository petData = new PetRepository();

	/*
	 * To hide the response element, using @Schema annotation, as follows, at
	 * operation level:
	 * 
	 * @param petId
	 * 
	 * @return
	 * 
	 * @throws NotFoundException
	 */
	@Operation(summary = "通过ID查找", description = "当ID<10时返回宠物。ID>10或非整数将模拟API错误条件", security = {
			@SecurityRequirement(name = "api_key"),
			@SecurityRequirement(name = "petstore_auth", scopes = { "write_pets,read_pets" }) })
	@Parameter(name = "petId", description = "需要提取的宠物的ID", example = "1", /* array = "range[1,5]", */required = true)
	@ApiResponses(value = { @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(hidden = true))),
			@ApiResponse(responseCode = "400", description = "提供的ID无效"),
			@ApiResponse(responseCode = "404", description = "未找到宠物", content = @Content) })
	@RequestMapping(value = "/{petId}", method = GET)
	public ResponseEntity<Pet> getPetById(@PathVariable("petId") String petId) throws NotFoundException {
		Pet pet = petData.get(Long.valueOf(petId));
		if (null != pet) {
			return ResponseEntity.ok(pet);
		} else {
			return new ResponseEntity<>(HttpStatus.NOT_FOUND);
			// throw new NotFoundException(404, "未找到宠物");
		}
	}

	@Operation(summary = "添加新宠物")
	@Parameters({ @Parameter(name = "pet", description = "向宠物店中添加新宠物", required = true)})
	@ApiResponses(value = { @ApiResponse(responseCode = "405", description = "输入无效") })
	@RequestMapping(method = POST)
	public ResponseEntity<String> addPet(@RequestBody Pet pet) {
		petData.add(pet);
		return ResponseEntity.ok("SUCCESS");
	}

	@Operation(summary = "修改宠物", security = @SecurityRequirement(name = "petstore_auth", scopes = { "write_pets",
			"read_pets" }))
	@ApiResponses(value = { @ApiResponse(responseCode = "400", description = "提供的ID无效"),
			@ApiResponse(responseCode = "404", description = "未找到宠物"),
			@ApiResponse(responseCode = "405", description = "验证异常") })
	@Parameters({ @Parameter(name = "pet", description = "对宠物数据进行修改", required = true) })
	@RequestMapping(method = PUT)
	public ResponseEntity<String> updatePet(
			/* @Parameter(value = "对宠物数据进行修改", required = true) */ @RequestBody Pet pet) {
		petData.add(pet);
		return ResponseEntity.ok("SUCCESS");
	}

	/**
	 * TODO: This renders parameter as
	 *
	 * "name": "status", "in": "query", "description": "Status values that need to
	 * be considered for filter", "required": false, "type": "array", "items":
	 * {"type": "string"}, "collectionFormat": "multi", "default": "available"
	 */
	@Operation(summary = "查找宠物状态", description = "多个状态值用逗号分隔的字符串提供", security = @SecurityRequirement(name = "petstore_auth", scopes = {
			"write_pets", "read_pets" }))
	@ApiResponses(value = { @ApiResponse(responseCode = "400", description = "无效的状态值") })
	@Parameters({
			@Parameter(name = "status", description = "需要考虑用于筛选的状态值"/*
																	 * , allowableValues = "available,pending,sold",
																	 * allowMultiple = true
																	 */)

	})

	@RequestMapping(value = "/findByStatus", method = GET)
	public ResponseEntity<List<Pet>> findPetsByStatus(@RequestParam("status") String status) {
		return ResponseEntity.ok(petData.findPetByStatus(status));
	}
	@Operation(summary = "按标签查找宠物", description = "多个标签可以用逗号分隔的字符串提供。使用tag1、tag2、tag3进行测试。", /*
																								 * response = Pet.class,
																								 * responseContainer =
																								 * "List",
																								 */
			security = @SecurityRequirement(name = "petstore_auth", scopes = {"write_pets", "read_pets" }))
	@ApiResponses(value = { @ApiResponse(responseCode = "400", description = "Invalid tag value") })
	@Parameters({
	@Parameter(name="tags",description="要筛选的标签" /*, allowMultiple = true */)})
	@Deprecated
	/**
	 * TODO: This renders the parameter as "name": "tags", "in": "query",
	 * "description": "Tags to filter by", "required": false, "type": "array",
	 * "items": {"type": "string"}, "collectionFormat": "multi"
	 */
	@RequestMapping(value = "/findByTags", method = GET)
	public ResponseEntity<List<Pet>> findPetsByTags(@RequestParam("tags") String tags) {
		return ResponseEntity.ok(petData.findPetByTags(tags));
	}

	static class PetRepository extends MapBackedRepository<Long, Pet> {
		public List<Pet> findPetByStatus(String status) {
			return where(Pets.statusIs(status));
		}

		public List<Pet> findPetByTags(String tags) {
			return where(Pets.tagsContain(tags));
		}
	}
}
